package com.zb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.entity.ZjWorkFeeLog;
import com.zb.entity.ZjWorkFeeLogImage;
import com.zb.list.WorkFeeLogListVo;
import com.zb.mapper.ZjWorkFeeLogMapper;
import com.zb.result.PageUtil;
import com.zb.service.ZjWorkFeeLogImageService;
import com.zb.service.ZjWorkFeeLogService;
import com.zb.utils.TransactionUtil;
import com.zb.utils.ZbManager;
import com.zb.vo.WorkFeeLogVo;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 工单费用记录表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2023-10-25
 */
@Service
public class ZjWorkFeeLogServiceImpl extends ServiceImpl<ZjWorkFeeLogMapper, ZjWorkFeeLog> implements ZjWorkFeeLogService {

    @Resource(name = "asyncServiceExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Resource
    private PlatformTransactionManager platformTransactionManager;
    @Resource
    private ZjWorkFeeLogImageService workFeeLogImageService;

    // 保存客服操作的工单费用记录
    @Override
    public void saveServiceFeeLog(WorkFeeLogVo workFeeLogVo) {
        List<WorkFeeLogVo> workFeeLogVos = new ArrayList<>();
        workFeeLogVos.add(workFeeLogVo);
        saveServiceFeeLog(workFeeLogVos);
    }

    // 批量保存客服操作的工单费用记录
    @Override
    public void saveServiceFeeLog(List<WorkFeeLogVo> workFeeLogVos) {
        if (CollectionUtil.isEmpty(workFeeLogVos)) {
            return;
        }
        List<ZjWorkFeeLog> logs = new ArrayList<>();
        List<ZjWorkFeeLogImage> images = new ArrayList<>();
        getFeeData(1, workFeeLogVos, logs, images);
        save(logs, images);
    }

    // 保存移动端网点操作的工单费用记录
    @Override
    public void saveMobileNetworkFeeLog(WorkFeeLogVo workFeeLogVo) {
        List<WorkFeeLogVo> workFeeLogVos = new ArrayList<>();
        workFeeLogVos.add(workFeeLogVo);
        saveMobileNetworkFeeLog(workFeeLogVos);
    }

    // 批量保存移动端网点操作的工单费用记录
    @Override
    public void saveMobileNetworkFeeLog(List<WorkFeeLogVo> workFeeLogVos) {
        if (CollectionUtil.isEmpty(workFeeLogVos)) {
            return;
        }
        List<ZjWorkFeeLog> logs = new ArrayList<>();
        List<ZjWorkFeeLogImage> images = new ArrayList<>();
        getFeeData(2, workFeeLogVos, logs, images);
        save(logs, images);
    }

    // 保存第三方系统操作的工单费用记录
    @Override
    public void saveThirdSystemFeeLog(WorkFeeLogVo workFeeLogVo) {
        List<WorkFeeLogVo> workFeeLogVos = new ArrayList<>();
        workFeeLogVos.add(workFeeLogVo);
        saveThirdSystemFeeLog(workFeeLogVos);
    }

    // 批量保存第三方系统操作的工单费用记录
    @Override
    public void saveThirdSystemFeeLog(List<WorkFeeLogVo> workFeeLogVos) {
        if (CollectionUtil.isEmpty(workFeeLogVos)) {
            return;
        }
        List<ZjWorkFeeLog> logs = new ArrayList<>();
        List<ZjWorkFeeLogImage> images = new ArrayList<>();
        getFeeData(3, workFeeLogVos, logs, images);
        save(logs, images);
    }


    private void getFeeData(Integer createEmpType, List<WorkFeeLogVo> workFeeLogVos, List<ZjWorkFeeLog> logs, List<ZjWorkFeeLogImage> images) {
        ZjWorkFeeLog log= null;
        for (WorkFeeLogVo vo : workFeeLogVos) {
            log = new ZjWorkFeeLog();
            BeanUtil.copyProperties(vo, log);
            log.setId(IdWorker.getId());
            log.setCreateEmpType(createEmpType);
            log.setContent(null == log.getContent()? "" : log.getContent());
            logs.add(log);
            if (CollectionUtil.isNotEmpty(vo.getImages())) {
                for (String im : vo.getImages()) {
                    ZjWorkFeeLogImage image = new ZjWorkFeeLogImage();
                    image.setId(IdWorker.getId());
                    image.setCustAccId(vo.getCustAccId());
                    image.setWorkFeeLogId(log.getId());
                    image.setImage(im);
                    images.add(image);
                }
            }
        }
    }

    private void save(List<ZjWorkFeeLog> logs, List<ZjWorkFeeLogImage> images) {
        threadPoolTaskExecutor.execute(() -> {
            TransactionStatus status = platformTransactionManager.getTransaction(TransactionUtil.transactionDefinition());
            try {
                this.saveBatch(logs);
                workFeeLogImageService.saveBatch(images);
                platformTransactionManager.commit(status);
            }catch (Exception e) {
                platformTransactionManager.rollback(status);
                ZbManager.log.error("添加工单费用项目失败：" + e);
            }
        });
    }


    // 根据服务项目ID获取服务费用项目日志记录列表
    @Override
    public Map<String, Object> getOrderFeeLogList(Long workFeeId, PageUtil pageUtil) {
        PageUtil.setPageLimit(pageUtil);
        QueryWrapper<ZjWorkFeeLog> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        wrapper.select("id", "create_emp_type", "create_emp", "event", "content", "gmt_create");
        wrapper.eq("work_fee_id", workFeeId);
        Page<ZjWorkFeeLog> page = this.page(new Page<>(pageUtil.getPage(), pageUtil.getLimit()), wrapper);
        List<ZjWorkFeeLogImage> images = workFeeLogImageService.getByWorkFeeLogIds(page.getRecords().stream().map(ZjWorkFeeLog::getId).toList());

        List<WorkFeeLogListVo> voList = page.getRecords().stream().map(log -> {
            WorkFeeLogListVo vo = new WorkFeeLogListVo();
            BeanUtil.copyProperties(log, vo);
            vo.setCreateEmpType(log.getCreateEmpType() == 1? "系统客服" : log.getCreateEmpType() == 2? "服务商移动端" : log.getCreateEmpType() == 3? "第三方系统" : "品牌商家");
            vo.setCreateTime(log.getGmtCreate());
            vo.setImages(images.stream().filter(f -> Objects.equals(f.getWorkFeeLogId(), log.getId())).map(ZjWorkFeeLogImage::getImage).toList());
            return vo;
        }).toList();
        return PageUtil.pageList(page.getCurrent(), page.getSize(), page.getTotal(), voList);
    }
}
